import os
import time
import resources_rc
import numpy as np
import base64
from PyQt5.QtWidgets import QWidget

from src.common.utils.websocket.WebSocketUtil import WebSocketUtil
from src.config import config
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
import cv2
# from hikvisionapi import Client
from PyQt5.QtGui import QImage, QPixmap

from src.views.home import *
from src.common.utils.http.httpUtil import HttpUtil
http = HttpUtil("http://")

class UIHomeView(QWidget, Ui_Form):
    def __init__(self):
        super(UIHomeView, self).__init__()
        self.setupUi(self)
        self.initParams()
        self.initUI()
        self.initSlot()
        self.initMethod()
        self.initAction()

    def initParams(self):
        self.timer_camera = QTimer()  # 初始化定时器-摄像头
        # self.timerDateTime = QTimer()  # 初始化定时器-日期时间
        self.cap = None
        self.message = QtWidgets.QMessageBox  # 初始化消息弹框，information消息，critical失败
        self.tmsg = message(self)  # 初始化线程弹框，不堵塞
        self.tmsg.signal.connect(self.btnClick)
        self.saveCamera = False
        self.saveVideo = False
        self.motorState1 = 0
        self.motorState2 = 1
        self.isCameraShow = False
        self.cameraStatus = False
        self.cameraData = []
        self.logCount = 1
        self.lastLog = None
        self.saveVideoIndex = 1
        self.flag = None
        self.image = None
        self.count = 0
        self.lastTime = time.time()
        self.videoWriter = None

    def btnClick(self, status, title, content):
        if status == self.tmsg.code.info:
            self.message.information(self, title, content)
        elif status == self.tmsg.code.error:
            self.message.critical(self, title, content)
        elif status == self.tmsg.code.warning:
            self.message.warning(self, title, content)

    def initAction(self):
        self.lightSwichPBClickCallback = None
        self.lightPowerPBClickCallback = None
        self.motorStateSwichPBClickCallback = None
        self.motorStateSwich2PBClickCallback = None
        self.metersLenghtResetPBClickCallback = None
        self.CBClickCallback = None
        self.speedSavePBClickCallback = None

    def initUI(self):
        file = QtCore.QFile(':qss/qss/main.qss')
        file.open(QtCore.QFile.ReadOnly)
        styleSheet = file.readAll()
        styleSheet = str(styleSheet)[1:]
        self.setStyleSheet(styleSheet)

    def initSlot(self):
        self.timer_camera.timeout.connect(self.cameraShow)
        # self.timerDateTime.timeout.connect(self.setDateTimeUI)

        self.pushButton_2.clicked.connect(self.takeAPictrue)
        self.pushButton_6.clicked.connect(self.pictureRecording)
        self.pushButton.clicked.connect(lambda: self.openCameraScreenShotPath('jpg/'))
        self.pushButton_7.clicked.connect(lambda: self.openCameraScreenShotPath('avi/'))
        self.initLightSlot([1])
        self.pushButton_9.clicked.connect(lambda: self.motorStateSwichPBClick(self.motorState1))
        self.pushButton_10.clicked.connect(lambda: self.motorStateSwich2PBClick(self.motorState2))
        self.pushButton_3.clicked.connect(self.metersLenghtResetPBClick)
        # self.motor_CB.activated['int'].connect(lambda: self.CBClick('motor'))
        # self.gasPump_CB.activated['int'].connect(lambda: self.CBClick('gasPump'))
        self.pushButton_8.clicked.connect(lambda: self.CBClick('motor', True))
        self.pushButton_12.clicked.connect(lambda: self.CBClick('motor', False))
        self.pushButton_11.clicked.connect(lambda: self.CBClick('gasPump', True))
        self.pushButton_13.clicked.connect(lambda: self.CBClick('gasPump', False))
        # self.pushButton_4.clicked.connect(lambda: self.speedSavePBClick('motor'))
        # self.pushButton_5.clicked.connect(lambda: self.speedSavePBClick('gasPump'))
        self.motor_SB.valueChanged['int'].connect(self.motorValueChange)
        self.gasPump_SB.valueChanged['int'].connect(self.gasPumpValueChange)

    def initLightSlot(self, lis):
        def initLightSlot(index):
            eval(f'self.light{index}_swich_PB').clicked.connect(lambda: self.lightSwichPBClick(index))
            eval(f'self.light{index}_800power_PB').clicked.connect(lambda: self.lightPowerPBClick(index, 1))
            eval(f'self.light{index}_1000power_PB').clicked.connect(lambda: self.lightPowerPBClick(index, 2))
            eval(f'self.light{index}_1500power_PB').clicked.connect(lambda: self.lightPowerPBClick(index, 3))
        for index in lis:
            initLightSlot(index)

    def initMethod(self):
        # self.timerDateTime.start(1000)
        pass

    # region setUI
    def setUI(self, dic):
        self.setLightUI("light1", dic['light_swich1'], dic['light_power1'])
        # self.setLightUI("light2", dic['light_swich2'], dic['light_power2'])
        # self.setLightUI("light3", dic['light_swich3'], dic['light_power3'])
        # self.setLightUI("light4", dic['light_swich4'], dic['light_power4'])
        self.setMotorStateUI(dic['motorState'])
        self.label_40.setText(f"{dic['temp1']}℃")
        self.label_41.setText(f"{dic['temp2']}℃")
        self.label_42.setText(f"{dic['temp3']}℃")
        self.label_44.setText(f"{dic['pressure']}MPa")
        self.label_49.setText(f"{dic['meters']}m")
        # self.setComboBoxUI('gasPump_CB', dic['gasPump'])
        # self.setComboBoxUI('motor_CB', dic['motor'])
        if int(dic['motor']) == 1:
            # self.pushButton_8.setStyleSheet("background-color: rgb(130, 130, 130);")
            # self.pushButton_8.setEnabled(False)
            # self.pushButton_12.setStyleSheet("background-color: rgb(255, 0, 0);")
            # self.pushButton_12.setEnabled(True)
            self.label_3.setStyleSheet("color: rgb(0, 255, 0);border: 0px;")
        else:
            self.label_3.setStyleSheet("color: rgb(255, 0, 0);border: 0px;")
            # self.pushButton_8.setStyleSheet("background-color: rgb(0, 170, 0);")
            # self.pushButton_8.setEnabled(True)
            # self.pushButton_12.setStyleSheet("background-color: rgb(130, 130, 130);")
            # self.pushButton_12.setEnabled(False)
        if int(dic['gasPump']) == 2:
            # self.pushButton_11.setStyleSheet("background-color: rgb(130, 130, 130);")
            # self.pushButton_11.setEnabled(False)
            # self.pushButton_13.setStyleSheet("background-color: rgb(255, 0, 0);")
            # self.pushButton_13.setEnabled(True)
            self.label_10.setStyleSheet("color: rgb(0, 255, 0);border: 0px;")
        else:
            # self.pushButton_11.setStyleSheet("background-color: rgb(0, 170, 0);")
            # self.pushButton_11.setEnabled(True)
            # self.pushButton_13.setStyleSheet("background-color: rgb(130, 130, 130);")
            # self.pushButton_13.setEnabled(False)
            self.label_10.setStyleSheet("color: rgb(255, 0, 0);border: 0px;")
        self.label_45.setText(f"{dic['metersSpeed']}m/min")

        self.label_46.setText(f"{dic['gasPumpSpeed']}HZ")
        self.label_19.setText(f"{dic['electricity1']}A")
        self.label_21.setText(f"{dic['electricity2']}A")
        self.label_24.setText(f"{dic['electricity3']}A")
        self.label_25.setText(f"{dic['electricity4']}A")

    def setLightUI(self, key, swich, power):
        if swich:
            exec(f'self.{key}_status_L.setStyleSheet("image: url(:/img/img/ico/light_on.png);")')
            exec(f'self.{key}_swich_PB.setStyleSheet("border-image: url(:/img/img/ico/swich_on.png);")')
        else:
            exec(f'self.{key}_status_L.setStyleSheet("image: url(:/img/img/ico/light_off.png);")')
            exec(f'self.{key}_swich_PB.setStyleSheet("border-image: url(:/img/img/ico/swich_off.png);")')
        if power==1:
            exec(f'self.{key}_800power_PB.setStyleSheet("background-color: rgb(255,204,0);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1000power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1500power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
        elif power==2:
            exec(f'self.{key}_800power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1000power_PB.setStyleSheet("background-color: rgb(255,204,0);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1500power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
        elif power==3:
            exec(f'self.{key}_800power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1000power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1500power_PB.setStyleSheet("background-color: rgb(255,204,0);color: rgb(255, 255, 255);")')
        else:
            exec(f'self.{key}_800power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1000power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')
            exec(f'self.{key}_1500power_PB.setStyleSheet("background-color: rgb(153,153,153);color: rgb(255, 255, 255);")')

    def setMotorStateUI(self, status):
        if status == 1:
            self.pushButton_9.setStyleSheet("border-image: url(:/img/img/ico/swich_on.png);")
            self.pushButton_10.setStyleSheet("border-image: url(:/img/img/ico/swich_pros.png);")
            self.motorState1 = 1
            self.motorState2 = 1
        elif status == 2:
            self.pushButton_9.setStyleSheet("border-image: url(:/img/img/ico/swich_on.png);")
            self.pushButton_10.setStyleSheet("border-image: url(:/img/img/ico/swich_cons.png);")
            self.motorState1 = 1
            self.motorState2 = 0
        elif status == 3:
            self.pushButton_9.setStyleSheet("border-image: url(:/img/img/ico/swich_off.png);")
            self.pushButton_10.setStyleSheet("border-image: url(:/img/img/ico/swich_cons.png);")
            self.motorState1 = 0
            self.motorState2 = 0
        else:
            self.pushButton_9.setStyleSheet("border-image: url(:/img/img/ico/swich_off.png);")
            self.pushButton_10.setStyleSheet("border-image: url(:/img/img/ico/swich_pros.png);")
            self.motorState1 = 0
            self.motorState2 = 1

    def setComboBoxUI(self, obj, status):
        cb = eval(f'self.{obj}')
        if (status == 1):
            cb.setCurrentIndex(0)
        elif (status == 2):
            cb.setCurrentIndex(1)
        elif (status == 5):
            cb.setCurrentIndex(2)
        elif (status == 7):
            cb.setCurrentIndex(3)

    def setDateTimeUI(self):
        timeStamp = int(time.time())
        timeArray = time.localtime(timeStamp)
        date_time = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)

        self.printLog(date_time)
    # endregion

    def cameraCheck(self):
        cameraUrl = config.camera.url
        try:
            cameraUrl = int(cameraUrl)
            if (self.isCameraShow == False):
                self.cameraOpen()
                return True
        except:
            if ('rtsp://' or 'rtmp://') and '@' in cameraUrl:
                url = cameraUrl.split('@')[1].split('/')[0]

                rst = http.get(url, timeout=3)
                if rst:
                    if (self.isCameraShow == False):
                        self.cameraOpen()
                        return False
                else:
                    print("网络摄像头不可用")
                    self.cameraClose()
                    return False
            elif ('rtsp://' or 'rtmp://') in cameraUrl:
                if (self.isCameraShow == False):
                    self.cameraOpen()
                    return False

    def cameraOpen(self):
        try:
            self.isCameraShow = True
            self.label_16.setStyleSheet("color: rgb(0, 255, 0);")
            self.cap = cv2.VideoCapture(config.camera.url)  # 初始化摄像头
            if (self.cap.isOpened()):
                # self.timer_camera.start(int(1000/config.camera.fps))
                self.fourcc = cv2.VideoWriter_fourcc(*'XVID')
            else:
                self.cameraClose()
            # try:
            #     cameraUrl = config.camera.url
            #     if ('rtsp://' or 'rtmp://') and '@' in cameraUrl:
            #         url = 'http://' + cameraUrl.split('@')[1].split('/')[0]
            #         username, password = cameraUrl.split('@')[0].replace('rtsp://', '').replace('rtmp://', '').split(':')
            #
            #         self.cap = Client(url, username, password)
            #         self.fourcc = cv2.VideoWriter_fourcc(*'XVID')
            # except Exception as e:
            #     self.cameraClose()
            #     print(e)
        except Exception as e:
            print(f'打开摄像头失败：{e}')
            self.cameraClose()

    def cameraClose(self):
        self.isCameraShow = False
        self.label_16.setStyleSheet("color: rgb(255, 0, 0);")
        if (self.cap.isOpened()):
            self.cap.close()
        self.cap = None
        # self.timer_camera.stop()
        self.fourcc = None

    # region Slot
    def getCameraFrame(self):
        count = 0
        lastTime = time.time()
        while True:
            if (not self.cap or not self.isCameraShow): continue
            self.flag, self.image = self.cap.read()
            count += 1
            if (time.time()-lastTime>=1):
                # print(f"read:{count}")
                lastTime = time.time()
                count = 0

            if (self.saveVideo):
                # if (self.saveVideoIndex == 1):
                #     self.cameraData.append(self.image)
                # self.saveVideoIndex += 1
                # if (self.saveVideoIndex == 5):
                #     self.saveVideoIndex = 1
                self.cameraData.append(self.image)
                # self.videoWriter.write(self.image)

            # try:
            #     vid = self.cap.Streaming.channels[102].picture(method='get', type='opaque_data')
            #
            #     bytes = b''
            #     for chunk in vid.iter_content(chunk_size=1024):
            #
            #         bytes += chunk
            #         a = bytes.find(b'\xff\xd8')
            #         b = bytes.find(b'\xff\xd9')
            #         if a != -1 and b != -1:
            #             jpg = bytes[a:b + 2]
            #             bytes = bytes[b + 2:]
            #             self.image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
            #             if (self.image.all() != None): self.flag = True
            # except Exception as e:
            #     self.flag = False

    def cameraShow(self):
        self.count+=1
        if (time.time() - self.lastTime>=1):
            # print(f"show:{self.count}")
            self.lastTime=time.time()
            self.count=0
        if (not self.cap or not self.isCameraShow):
            self.cameraStatus = False
            self.label_14.setStyleSheet("color: rgb(255, 0, 0);")
            return

        if (self.flag != self.cameraStatus):
            self.cameraStatus = self.flag
            if (self.flag):
                self.label_14.setStyleSheet("color: rgb(0, 255, 0);")
            else:
                self.label_14.setStyleSheet("color: rgb(255, 0, 0);")
        if not self.flag: return
        height = self.label_4.height()
        width = self.label_4.width()
        show = cv2.resize(self.image, (width, height))
        show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
        h, w, ch = show.shape
        bytesPerLine = ch * w
        showImage = QImage(show.data, w, h, bytesPerLine, QImage.Format_RGB888)
        # cv2.imshow( "",show)
        self.label_4.setPixmap(QPixmap.fromImage(showImage))
        if self.saveCamera:
            self.saveCamera = False
            cv2.imwrite(config.camera.screenShotPath+f"jpg/{int(time.time())}.jpg", self.image)

    def takeAPictrue(self):
        if not self.saveCamera:
            dirs = config.camera.screenShotPath + "jpg/"
            if not os.path.exists(dirs):
                os.makedirs(dirs)
            self.saveCamera = True

    def pictureRecording(self):
        if self.saveVideo:
            self.saveVideo = False
            self.pushButton_6.setText("   录像   ")
            # self.videoWriter = None
        else:
            filename, ok = QtWidgets.QInputDialog.getText(self, "录像", "录像名称：", QtWidgets.QLineEdit.Normal, "")

            if not ok or filename == '':
                return
            self.saveVideo = True
            self.pushButton_6.setText("  结束录像  ")
            dirs = config.camera.screenShotPath+"avi/"
            if not os.path.exists(dirs):
                os.makedirs(dirs)
            size = (int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
            self.videoWriter = cv2.VideoWriter(config.camera.screenShotPath+f"avi/{filename}.avi", self.fourcc, 20.0, size)

    def openCameraScreenShotPath(self, path):
        dirs = config.camera.screenShotPath + path
        if not os.path.exists(dirs):
            os.makedirs(dirs)
        os.startfile(dirs)

    def lightSwichPBClick(self, index):
        # print(f"点击了{index}按钮")
        self.printLog(f"点击了辐射灯按钮")
        # self.message.information(self, "消息提示", f"点击了灯{index}按钮")
        if self.lightSwichPBClickCallback:
            self.lightSwichPBClickCallback(index)

    def lightPowerPBClick(self, index, value):
        # print(f"点击了{index}-{value}按钮")
        self.printLog(f"点击了辐射灯功率{value}按钮")
        # self.message.information(self, "消息提示", f"点击了{index}-{value}按钮")
        if self.lightPowerPBClickCallback:
            self.lightPowerPBClickCallback(index, value)

    def motorStateSwichPBClick(self, value):
        # print(f"点击了电机控制开关按钮")
        self.printLog(f"点击了电机控制开关按钮")
        # self.message.information(self, "消息提示", f"点击了电机控制开关按钮")
        if self.motorStateSwichPBClickCallback:
            self.motorStateSwichPBClickCallback(value)

    def motorStateSwich2PBClick(self, value):
        # print(f"点击了电机控制开关2按钮")
        self.printLog(f"点击了电机正反转按钮")
        # self.message.information(self, "消息提示", f"点击了电机控制开关2按钮")
        if self.motorStateSwich2PBClickCallback:
            self.motorStateSwich2PBClickCallback(value)

    def metersLenghtResetPBClick(self):
        # print(f"点击了收盘电机长度清零按钮")
        self.printLog(f"点击了计米器长度清零按钮")
        # self.message.information(self, "消息提示", f"点击了收盘电机长度清零按钮")
        if self.metersLenghtResetPBClickCallback:
            self.metersLenghtResetPBClickCallback()

    def CBClick(self, key, status):
        # print(f"点击了收盘电机")
        # index = eval(f'self.{key}_CB').currentIndex()
        self.printLog(f"点击了{key}_{status}")
        # self.message.information(self, "消息提示", f"点击了{key}_{status}")
        if self.CBClickCallback:
            self.CBClickCallback(key, status)

    def motorValueChange(self, value):
        self.SBValueChange('motor', value)

    def gasPumpValueChange(self, value):
        self.SBValueChange('gasPump', value)

    def SBValueChange(self, key, value):
        # print(key, value)
        if self.speedSavePBClickCallback:
            self.speedSavePBClickCallback(key, value)

    def speedSavePBClick(self, key):
        speed = eval(f'self.{key}_SB').value()
        self.message.information(self, "消息提示", f"点击了{key}_{speed}")
        if self.speedSavePBClickCallback:
            self.speedSavePBClickCallback(key, speed)
    # endregion

    def printLog(self, msg):
        if self.lastLog == msg:
            self.logCount = self.logCount + 1
            msg += f' * {self.logCount}'
        else:
            self.logCount = 1
            self.lastLog = msg
        self.label_2.setText(msg)


class message(QThread):
    signal = pyqtSignal(int, str, str)

    def __init__(self, Window):
        super(message, self).__init__()
        self.window = Window

    def run(self):
        self.signal.emit()

    class code:
        info = 1
        warning = 2
        error = 3


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ui = UIHomeView()
    ui.show()
    os._exit(app.exec_())